/**
 * Project: core.common
 * 
 * File Created at 2016年4月5日
 * 
 * Copyright 2015-2015 dx.com Croporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * DongXue software Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with dx.com.
 */
package com.dx.pf.commons.balance;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/** 
* @ClassName: PopularUriReader 
* @Description: 定时读取更新热门uri，该定时器的工作方式是根据设定间隔时间定时读取热门uri文件，更新Context中uriHashMap,
 * 在更新的过程中，会判断原uriHashMap中的uri的合法性，并且更新为增量更新，非全量更新
* @author wuzhenfang(wzfbj2008@163.com)
* @date 2016年4月5日 上午12:24:16 
* @version V1.0 
*/
public class PopularUriReader implements Runnable {
	 private ScheduledExecutorService scheduler;//JDK1.5+
	    private int initialDelay = 1; //首次执行的延迟时间 默认1  单位毫秒
	    private int delay = 6000;//一次执行终止和下一次执行开始之间的延迟 默认1分钟  单位毫秒
	    private String popularUrisFile;//热门uri文件

	    public PopularUriReader() {
	    }

	    public PopularUriReader(String popularUrisFile) {
	        this.popularUrisFile = popularUrisFile;
	    }

	    /**
	     * 启动定时读取popular uri的线程
	     */
	    public void start() {
	        scheduler = Executors.newScheduledThreadPool(1);
	        if (initialDelay <= 0) initialDelay = 1; //如果配置值小于1则设置为默认值为1
	        if (delay <= 0) delay = 60000; //如果间隔小于1则设置为默认值1分钟
	        scheduler.scheduleWithFixedDelay(this, initialDelay, delay, TimeUnit.MILLISECONDS);
	        System.out.println("定时器：[HoturiReader]已启动>>>");
	    }

	    public void destroy() {
	        if (scheduler != null) {
	            scheduler.shutdown();
	        }
	        System.out.println("定时器：[PopularUriReader]已正常关闭>>>");
	    }

	    @Override
	    public void run() {
	        System.out.println("热门uri开始重新加载...");
	        Context context = Context.getInstance();
	        File file = new File(this.popularUrisFile);
	        try {
	            BufferedReader br = new BufferedReader(new FileReader(file));
	            Set<Long> uriSet = new HashSet<Long>();
	            String uriStr;
	            while ((uriStr = br.readLine()) != null) {
	                uriStr = uriStr.trim();
	                if (!"".equals(uriStr)) {
	                    long hashCode = context.hash(uriStr);
	                    uriSet.add(hashCode);
	                    if (!context.getUriHashMap().containsKey(hashCode)) {
	                         /*添加新的热门URI*/
	                        context.putUriHash(hashCode, Context.getInstance().getRandServer());
	                    }
	                }
	            }
	            /*移除失效的热门URI*/
	            Set<Long> inValideKey=new HashSet<Long>();
	            for (Map.Entry<Long, Integer> entry : context.getUriHashMap().entrySet()) {
	                if (!uriSet.contains(entry.getKey())) {
	                    inValideKey.add(entry.getKey());
	                }
	            }
	            for(Long key:inValideKey){
	                context.removeUriHash(key);
	            }
	            System.out.println("热门uri重新加载完成>>>"+ context.getUriHashMap().size());
	            br.close();
	        } catch (FileNotFoundException e) {
	            e.printStackTrace();
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	    }

	    public void setInitialDelay(int initialDelay) {
	        this.initialDelay = initialDelay;
	    }

	    public void setDelay(int delay) {
	        this.delay = delay;
	    }

	    /**
	     * 设置存储热门Uri文件的位置
	     *
	     * @param popularUrisFile
	     */
	    public void setPopularUrisFile(String popularUrisFile) {
	        this.popularUrisFile = popularUrisFile;
	    }
}
